#include "stdafx.h"
#include "TpcCatalog.h"

#include <string>
#include <fstream>
#include <map>
#include <deque>
using namespace std;

#include <filesystem>
using namespace tr2::sys;

namespace Tpc
{
	void addCatalogFile(string filename, map<string,string>& catalogs)
	{
		// TODO: Error handling!!
		header header;
		ifstream infile;
		infile.open(filename, ifstream::in | ifstream::binary);
		infile.read((char*)(&header), sizeof(header));

		deque<folderEntry> currentPath;
		folderEntry rootEntry;
		infile.read((char*)(&rootEntry), sizeof(folderEntry));
		rootEntry.name[0] = 0;
		currentPath.push_back(rootEntry);

		bool readingFolderEntry = true;
		while (currentPath.size() > 0)
		{
			if (readingFolderEntry)
			{
				folderEntry entry;
				infile.read(reinterpret_cast<char*>(&entry), sizeof(entry));

				for (deque<folderEntry>::iterator i = currentPath.begin(); i < currentPath.end(); i ++)
					i->folders --;

				currentPath.push_back(entry);
				if (strlen(entry.name) == 0)
					readingFolderEntry = false;
			}
			else
			{
				fileEntry entry;
				infile.read((char*)(&entry), sizeof(entry));

				string path;
				for (deque<folderEntry>::iterator i = currentPath.begin(); i < currentPath.end(); i ++)
				{
					path += i->name;
					i->files --;
				}

				string name(entry.name, entry.name+8);

				// TODO: How to deal with duplicates??
				catalogs.insert(pair<string,string>(name,path));

				if (currentPath.back().files == 0)
				{
					readingFolderEntry = true;
					currentPath.pop_back();
					while (currentPath.size() > 0 && currentPath.back().folders == 0)
						currentPath.pop_back();
				}
			}
		}
	}

	void loadCatalogs(string catalogPath, map<string,string>& catalogs)
	{
		if (!exists(path(catalogPath)))
			throw "Cannot locate catalog path: " + catalogPath;

		for (directory_iterator i(catalogPath); i != directory_iterator(); ++ i)
			if (is_regular_file(i->status()) && extension(i->path()) == ".tpc")
				addCatalogFile(catalogPath + "\\" + i->path().filename(), catalogs);
	}

}